CNMF is blind source separation toolbox for cell detection and signal extraction.
Here we illustrate how one can use the ROIs detected by CNMF, and use FISSA to extract and decontaminate the traces.
In this tutorial, we assume the user is using the MATLAB implementation of CNMF. As such, this also serves as a tutorial on how to import data from MATLAB into Python to use with FISSA.
However, note that there is also a Python implementation of CNMF, which you can use instead to keep your whole workflow in Python.
Reference: Pnevmatikakis, E.A., Soudry, D., Gao, Y., Machado, T., Merel, J., ... & Paninski, L. (2016). Simultaneous denoising, deconvolution, and demixing of calcium imaging data. Neuron 89(2):285-299, doi: 10.1016/j.neuron.2015.11.037.
In [1]:
# FISSA toolbox
import fissa
# Matfile loading utility
from scipy.io import loadmat
# Plotting toolbox, with notebook embedding options
import holoviews as hv
%load_ext holoviews.ipython
%output widgets='embed'
We ran CNMF in MATLAB using the run_pipeline.m
script available from the CNMF repository on our example data (found at ../exampleData/20150529/).
We saved the Coor
and F_df
variables generated by that script into a .mat
file (cNMFdata.mat) which we now load here.
In [2]:
# Load data from cNMFdata.mat file
cNMFdata = loadmat('cNMFdata')['dat']
# Get the F_df recording traces out of the loaded object
F_df = cNMFdata['F_df'][0, 0]
# Get the ROI outlines out of the loaded object
Coor = cNMFdata['Coor'][0, 0]
In [3]:
# Plotting lines surrounding each of the ROIs
fig = hv.Overlay()
for i in range(len(Coor)):
x = Coor[i, 0][0]
y = Coor[i, 0][1]
fig *= hv.Curve(zip(x, y))
fig
Out[3]:
FISSA needs ROIs to be provided either as an ImageJ zip file, or a set of numpy arrays.
CNMF can output ROIs in coordinates (as we imported above), which can be directly read into FISSA. A given roi after importing from MATLAB is given as
Coor[i, 0]
FISSA expects a set of rois to be given as a list of lists,
[[roiA1, roiA2, roiA3, ...]]
so we will need to change the format of the ROIs first.
In [4]:
numROI = len(Coor)
rois_FISSA = [[Coor[i, 0][0], Coor[i, 0][1]] for i in range(numROI)]
Which can then be put into FISSA and run as follows.
In [5]:
output_folder = 'fissa_cnmf_example'
tiff_folder = 'exampleData/20150529/'
exp = fissa.Experiment(tiff_folder, [rois_FISSA], output_folder)
exp.separate(redo_prep=True)
In [6]:
%%opts Curve {+axiswise}
def plot_cell_regions(roi_polys, plot_neuropil=False):
'''
Plot a single cell region, using holoviews.
'''
out = hv.Overlay()
if plot_neuropil:
# Plot the neuropil as well as the ROI
n_region = len(roi_polys)
else:
# Just plot the ROI, not the neuropil
n_region = 1
for i_region in range(n_region):
x = roi_polys[i_region][0][:, 1]
y = roi_polys[i_region][0][:, 0]
out *= hv.Curve(zip(x, y))
return out
i_trial = 0
# Generate outlines around for all detected regions, indicating neuropil subregions
region_plots = {
i_cell: plot_cell_regions(exp.roi_polys[i_cell, i_trial], plot_neuropil=True)
for i_cell in range(exp.nCell)
}
# Generate plots for raw extracts and neuropil removed
traces_plots = {
i_cell: hv.Curve(exp.raw[i_cell][i_trial][0, :], label='CNMF') *
hv.Curve(exp.result[i_cell][i_trial][0, :], label='FISSA')
for i_cell in range(exp.nCell)
}
# Get average image
avg_img = hv.Raster(exp.means[i_trial])
# Render holoviews
avg_img * hv.HoloMap(region_plots, kdims=['Cell']) * fig + hv.HoloMap(traces_plots, kdims=['Cell'])
Out[6]:
(A) ROI contours, and the neuropil subregions defined by FISSA for the current cell.
(B) Signal extracted by CNMF (blue), and after decontaminating with FISSA (red)